package com.qf.events.listeners;

import com.qf.entity.SysLogininfor;
import com.qf.entity.SysUserInfo;
import com.qf.entity.SysUserOnline;
import com.qf.events.UserLoginEvent;
import com.qf.mapper.SysLogininforDao;
import com.qf.mapper.SysLogininforMapper;
import com.qf.mapper.SysUserOnlineDao;
import com.qf.mapper.SysUserOnlineMapper;
import com.qf.pojo.BaseUser;
import com.qf.service.UserService;
import com.qf.utils.RequestUtil;
import com.qf.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * @Author ztf
 * @Date 21:12 2021/12/30
 * 用户登录事件监听
 **/
@Component
public class UserLoginListener {
    private UserService userService;
    private SysUserOnlineDao sysUserOnlineDao;
    private SysUserOnlineMapper sysUserOnlineMapper;
    private SysLogininforDao sysLogininforDao;
    private SysLogininforMapper sysLogininforMapper;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Autowired
    public void setSysUserOnlineDao(SysUserOnlineDao sysUserOnlineDao) {
        this.sysUserOnlineDao = sysUserOnlineDao;
    }

    @Autowired
    public void setSysUserOnlineMapper(SysUserOnlineMapper sysUserOnlineMapper) {
        this.sysUserOnlineMapper = sysUserOnlineMapper;
    }

    @Autowired
    public void setSysLogininforDao(SysLogininforDao sysLogininforDao) {
        this.sysLogininforDao = sysLogininforDao;
    }

    @Autowired
    public void setSysLogininforMapper(SysLogininforMapper sysLogininforMapper) {
        this.sysLogininforMapper = sysLogininforMapper;
    }

    @EventListener
    public void onLoginSuccess(AuthenticationSuccessEvent loginEvent) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //BaseUser baseUser = SecurityUtils.getUser();
        //获取当前登录的用户
        BaseUser baseUser = (BaseUser) loginEvent.getAuthentication().getPrincipal();
        CompletableFuture.runAsync(() -> {//runAsync是不需要结果的异步
            try {
                SysUserInfo user = new SysUserInfo();
                user.setuId(baseUser.getUserId());
                //  Map<String, String> osAndBrowserInfo = RequestUtil.getOsAndBrowserInfo(request);//存放了是请求的系统和软件信息
                String ip = RequestUtil.getRemoteHost(request);//获取到用户的ip
                //  user.setLastLogin(user.getCurrentLogin());
                user.setCurrentLogin(new Date());
                // user.setLastLoginIp(user.getCurrentLoginIp());
                user.setCurrentLoginIp(ip);
                userService.updateUserLogin(user);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        CompletableFuture.runAsync(() -> {
            try {
                Map<String, String> osAndBrowserInfo = RequestUtil.getOsAndBrowserInfo(request);//存放了是请求的系统和软件信息
                String ip = RequestUtil.getRemoteHost(request);//获取到用户的ip
                SysUserOnline userOnline = new SysUserOnline();
                userOnline.setSessionId(request.getSession().getId());
                userOnline.setLoginName(baseUser.getUsername());
                userOnline.setStartTimestamp(new Date());
                userOnline.setStatus("1");//设置为在线
                userOnline.setIpaddr(ip);
                userOnline.setLoginLocation(RequestUtil.getLocationByIp(ip));//请求第三方服务器,需要时间,所以应该放到单独的线程中执行
                userOnline.setOs(osAndBrowserInfo.get("os"));
                userOnline.setBrowser(osAndBrowserInfo.get("browser"));
                userOnline.setExpireTime(30);
                //保存到数据库,发现有问题,当前用户的数据如果已经存在了 应该更新
                SysUserOnline currentLogin = sysUserOnlineMapper.selectByLoginName(baseUser.getUsername());//先查询一下
                if (currentLogin != null) {
                    //存在,删除
                    sysUserOnlineMapper.deleteByLoginName(baseUser.getUsername());
                }
                sysUserOnlineMapper.insertUserOnline(userOnline);

            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    @EventListener
    public void onLoginFail(AbstractAuthenticationFailureEvent failureEvent) {
        System.err.println("UserLoginListener中的方法onLoginFail 执行了");
    }

//    /**
//     * 更新用户的基本登录信息
//     *
//     * @param userLoginEvent 用户登录事件
//     */
//    @EventListener
//    public void updateUserInfo(UserLoginEvent userLoginEvent) {
//        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        BaseUser userInfo = SecurityUtils.getUser();
//        //通过异步执行当前操作
//        CompletableFuture.runAsync(() -> {
//            try {
//                //获取用户ip
//                String remoteHost = RequestUtil.getRemoteHost(request);
//                userInfo.setCurrentLogin(new Date());
//                userInfo.setCurrentLoginIp(remoteHost);
//                userService.updateUserLogin(userInfo);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        });
//    }
//
//    /**
//     * 更新用户在线状态
//     *
//     * @param userLoginEvent 登录事件
//     */
//    @EventListener
//    public void updateUserOnline(UserLoginEvent userLoginEvent) {
//        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        SysUserInfo userInfo = SecurityUtils.getUser();
//
//        //异步操作
//        CompletableFuture.runAsync(() -> {
//            try {
//                //获取系统与软件信息
//                Map<String, String> osAndBrowserInfo = RequestUtil.getOsAndBrowserInfo(request);
//                String remoteHost = RequestUtil.getRemoteHost(request);
//                SysUserOnline userOnline = new SysUserOnline();
//                userOnline.setSessionid(request.getSession().getId());
//                userOnline.setLoginName(userInfo.getUsername());
//                userOnline.setStartTimestamp(new Date());
//                userOnline.setStatus("1");//设置为在线
//                userOnline.setIpaddr(remoteHost);
//                userOnline.setLoginLocation(RequestUtil.getLocationByIp(remoteHost));//请求第三方服务器,需要时间,所以应该放到单独的线程中执行
//                userOnline.setOs(osAndBrowserInfo.get("os"));
//                userOnline.setBrowser(osAndBrowserInfo.get("browser"));
//                userOnline.setExpireTime(30);
//
//                //保存到数据库
//                //如果在线数据已存在则更新
//
//                SysUserOnline sysUserOnline = sysUserOnlineMapper.selectByLoginName(userOnline.getLoginName());
//
//                if (sysUserOnline != null) {
//                    sysUserOnlineMapper.deleteByLoginName(userOnline.getLoginName());
//                }
//                sysUserOnlineMapper.insertUserOnline(userOnline);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        });
//    }

    /**
     * 记录用户登录日志
     * @param userLoginEvent 登录事件
     */
    @EventListener
    public void onLoginLog(UserLoginEvent userLoginEvent) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        BaseUser userInfo = SecurityUtils.getUser();

        CompletableFuture.runAsync(() -> {
            //获取系统和软件信息
            Map<String, String> osAndBrowserInfo = RequestUtil.getOsAndBrowserInfo(request);
            String remoteHost = RequestUtil.getRemoteHost(request);
            String location = RequestUtil.getLocationByIp(remoteHost);
            SysLogininfor logininfor = new SysLogininfor();
            logininfor.setLoginName(userInfo.getUsername());
            logininfor.setIpaddr(remoteHost);
            logininfor.setLoginLocation(location);
            logininfor.setBrowser(osAndBrowserInfo.get("browser"));
            logininfor.setOs(osAndBrowserInfo.get("os"));
//            logininfor.setStatus(String.valueOf(userInfo.getStatus()));
            logininfor.setMsg("登录成功");
            logininfor.setLoginTime(new Date());

            //插入登入日志
            sysLogininforMapper.insertLogininfor(logininfor);
        });
    }


}
